"""Juggle Belfre: draws random patterns and queries for grades.

Juggle Belfre composes a grading session by drawing random patterns; one
pattern appears only one during a session. The grades are then added
to the database.

Juggle Belfre has the option of manual interruption during a session
which preserves grades collected so far. To interrupt a session, input
'x'. Be careful: the program will terminate without any warning!

All input forms are case insensitive.
"""

import random
import string
import os
import sys
import csv
import spoldzielnia

grade_list = []
juggle_question = "j"

# sets options with spoldzielnia.py module. 'opcje' is a tuple with options returned by the module.
opcje = spoldzielnia.konfigurator("belfre")
grade_count = opcje[0]
grades_to_store = opcje[1]
del opcje

# defines relevant lists with spoldzielnia.py module. "listy' is a tuple with lists returned by the module.
listy = spoldzielnia.czytacz()
trick_list = listy[0]
grades_string_list = listy[1]
tag_string_list = listy[2]
del listy

# validates number of database entries against grade_count value
if len(trick_list) < grade_count:
    print "grade_count option too big. Setting to default (20)."
    grade_count = 20
else:
    pass

# runs one session
def runsession():
    """Runs one grading session. Patterns aren't repeated within one session.
    """
    
    global rand_id_list
    rand_id_list = random.sample(range(0, len(trick_list)), grade_count)
    for zlicz in range(0, grade_count):
        current_id = int(rand_id_list[zlicz])
	#welcome message
        os.system(['clear','cls'][os.name == 'nt'])
        print ""
        print " " + str(grade_count) + " patterns out of all"
        print " ++++++++++++++++++++++"
        print ""
        print string.rjust(str(zlicz + 1), 5) + ". " + string.ljust(trick_list[current_id], 25)
        print ""
        grade_string = raw_input("Grade: ")

        # Validates input; is it a digit between 1 and 5?
        while grade_string.isdigit() == False or int(grade_string) not in range(1, 6):
            if grade_string == "x":
                juggle_question = "stop"
                global juggle_question
                os.system(['clear','cls'][os.name == 'nt'])
                break
            else:
                grade_string = raw_input("  * Oops! Accepted grades are 1 to 5 ('x' to interrupt): ")

        # Manual interruption handler that preserves the results obtained so far.
        if juggle_question == "stop":
            break
        else:
            grades_string_list[current_id] = grades_string_list[current_id] + grade_string
            grade_list.append(grade_string)
            print ""

def ChallengeMe():
    challenge_list_string = spoldzielnia.konfigurator("challenge")
    challenge_list = challenge_list_string.split(',')
    trick = random.choice(trick_list)
    challenge = random.choice(challenge_list)
    os.system(['clear','cls'][os.name == 'nt'])
    print ""
    print " Your challenge is:"
    print " ++++++++++++++++++"
    print ""
    print "   " + trick + " for " + challenge.strip()
    print ""
    raw_input(" Press any key...")
    os.system(['clear','cls'][os.name == 'nt'])

os.system(['clear','cls'][os.name == 'nt'])

while juggle_question in ["j", "i", "c", "stop"]:
    print ""
    print " What do you want to do now?  (" + str(grade_count) + " patterns in a session)"
    print ""
    print " [j] Juggle a session                 [x] Quit"
    print " [i] Issue a challenge"
    print " [c] Change the number of patterns"
    juggle_question = raw_input("? ").lower()
    while juggle_question not in ["j", "c", "i", "x"]:
        juggle_question = raw_input("  * Oops! This is not a valid keystroke. Try again... ").lower()

    if juggle_question == "j":
        runsession()
    elif juggle_question == "i":
        ChallengeMe()
    elif juggle_question == "c":
        # Manually sets number of the number of patterns in a session (with input validator).
        numb_string = raw_input("  * How many patterns in a session? ")
        while numb_string.isdigit() == False or numb_string == "0":
            numb_string = raw_input("    * Nice try, but try again. Write a number: ")
        grade_count = int(numb_string)
        os.system(['clear','cls'][os.name == 'nt'])
    else:
        os.system(['clear','cls'][os.name == 'nt'])
        pass

    if juggle_question == "j":
        # displays results
        print ""
        print "Results for this session:"
        print "-------------------------"
        print ""
        for count in range(0, grade_count):
            current_id = rand_id_list[count]
            print string.rjust(trick_list[current_id].strip(), 30) + string.center("=>", 6) + string.ljust(grade_list[count], 1)
        print ""
    else:
        pass

# checks for and eliminates superfluous grades
for zlicz in range(0, len(trick_list)):
    if len(grades_string_list[zlicz]) > grades_to_store:
        clip_by = len(grades_string_list[zlicz]) - grades_to_store
        grades_string_list[zlicz] = grades_string_list[zlicz][clip_by:]
    else:
        pass

# writes updated db file
spoldzielnia.pisacz(trick_list, grades_string_list, tag_string_list)

os.system(['clear','cls'][os.name == 'nt'])
